#include "IList.h"
#include <stdio.h>
#include <stdlib.h>

CListNode::CListNode()
{
    m_pPreNode = NULL;
    m_pNextNode = NULL;
}

CListNode::~CListNode()
{
    m_pPreNode = NULL;
    m_pNextNode = NULL;
}

CList::CList()
{
    m_len = 0;
    m_pHead = NULL;
    m_pTail = NULL;
}

void CList::clear()
{
    m_len = 0;
    m_pHead = NULL;
    m_pTail = NULL;
}


int CList::addNode(CListNode* pNode)
{
    if(m_len == 0)
    {
        m_pHead = pNode;
        m_pTail = pNode;

        pNode->m_pPreNode = NULL;
        pNode->m_pNextNode = NULL;
    }
    else
    {
        m_pTail->m_pNextNode = pNode;
        pNode->m_pPreNode = m_pTail;
        pNode->m_pNextNode = NULL;

        m_pTail = pNode;
    }
    m_len++;
    return m_len;
}

int CList::delNode(CListNode* pNode) 
{
    CListNode* pDelNode = findNode(pNode);
    if(pDelNode == NULL) return m_len;
    if(pDelNode->m_pPreNode != NULL)
    {
        pDelNode->m_pPreNode->m_pNextNode = pDelNode->m_pNextNode;
    }
    else
    {
        m_pHead = pDelNode->m_pNextNode;
    }
    if(pDelNode->m_pNextNode != NULL)
    {
        pDelNode->m_pNextNode->m_pPreNode = pDelNode->m_pPreNode;
    } 
    else
    {
        m_pTail = pDelNode->m_pPreNode;
    }
    delete pDelNode;
    m_len--;
    return m_len;
}

int CList::removeNode(CListNode* pNode)
{
    CListNode* pDelNode = findNode(pNode);
    if(pDelNode == NULL) return m_len;
    if(pDelNode->m_pPreNode != NULL)
    {
        pDelNode->m_pPreNode->m_pNextNode = pDelNode->m_pNextNode;
    }
    else
    {
        m_pHead = pDelNode->m_pNextNode;
    }
    if(pDelNode->m_pNextNode != NULL)
    {
        pDelNode->m_pNextNode->m_pPreNode = pDelNode->m_pPreNode;
    } 
    else
    {
        m_pTail = pDelNode->m_pPreNode;
    }
    pDelNode->m_pPreNode = NULL;
    pDelNode->m_pNextNode = NULL;
    m_len--;
    return m_len;
}

CListNode* CList::findNode(CListNode* pNode)
{
    if(m_len == 0) return NULL;
    for(CListNode* pCurNode = m_pHead;pCurNode!=NULL;pCurNode=pCurNode->m_pNextNode)
    {
        if(pCurNode->compare(pNode) == 0)
        {
            return pCurNode;
        }
    }
    return NULL;
}

void CList::dump()
{
    printf("== begin list ==\n");
    int i = 1;
    for(CListNode* pCurNode = m_pHead;pCurNode!=NULL;pCurNode=pCurNode->m_pNextNode)
    {
        printf("%d/%d: ",i++,m_len);pCurNode->print();
    }
    printf("== end list ==\n\n");
}

void CList::operator= (CList& node)
{
    this->m_len = node.m_len;
    this->m_pHead = node.m_pHead;
    this->m_pTail = node.m_pTail;
}

void CList::sortInc()
{
    CList incList;
    CListNode* pMinNode = NULL;
    do
    {
        pMinNode = findMinNode();
        if(pMinNode != NULL)
        {
            removeNode(pMinNode);
            incList.addNode(pMinNode);
        }
    }while(pMinNode != NULL);
    *this = incList;
}

void CList::sortDec()
{
    CList decList;
    CListNode* pMaxNode = NULL;
    do
    {
        pMaxNode = findMaxNode();
        if(pMaxNode != NULL)
        {
            removeNode(pMaxNode);
            decList.addNode(pMaxNode);
        }
    }while(pMaxNode != NULL);
    *this = decList;
}



CListNode* CList::findMinNode()
{
    CListNode* pMinNode = m_pHead;
    for(CListNode* pCurNode = m_pHead;pCurNode!=NULL;pCurNode=pCurNode->m_pNextNode)
    {
        if(pMinNode->compare(pCurNode) > 0)
        {
            pMinNode = pCurNode;
        }
    }
    return pMinNode;
}

CListNode* CList::findMaxNode()
{
    CListNode* pMaxNode = m_pHead;
    for(CListNode* pCurNode = m_pHead;pCurNode!=NULL;pCurNode=pCurNode->m_pNextNode)
    {
        if(pMaxNode->compare(pCurNode) < 0)
        {
            pMaxNode = pCurNode;
        }
    }
    return pMaxNode;
}


